Skip to content

[HTTPConnectionPool] Implementation switch #427

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 24, 2021

Conversation

fabianfett
Copy link
Member

This is the final pr to switch the implementation over to our new HTTPConnectionPool and Connections. There are some outstanding changes (#425, #426) that we want to land in smaller prs beforehand, but for everyone interested, this is your chance to play with the new implementation.

The failing unit tests are tests related logging, we will need to fix this before we can land this pr.

@fabianfett fabianfett marked this pull request as draft September 14, 2021 07:59
@fabianfett fabianfett force-pushed the ff-switch-implementation branch from 1fe5485 to efaf97c Compare September 14, 2021 09:16
Comment on lines 715 to +724
func succeed<Delegate: HTTPClientResponseDelegate>(promise: EventLoopPromise<Response>?,
with value: Response,
delegateType: Delegate.Type,
closing: Bool) {
self.releaseAssociatedConnection(delegateType: delegateType,
closing: closing).whenSuccess {
promise?.succeed(value)
}
promise?.succeed(value)
}

func fail<Delegate: HTTPClientResponseDelegate>(with error: Error,
delegateType: Delegate.Type) {
if let connection = self.connection {
self.releaseAssociatedConnection(delegateType: delegateType, closing: true)
.whenSuccess {
self.promise.fail(error)
connection.channel.close(promise: nil)
}
} else {
// this is used in tests where we don't want to bootstrap the whole connection pool
self.promise.fail(error)
}
}

func releaseAssociatedConnection<Delegate: HTTPClientResponseDelegate>(delegateType: Delegate.Type,
closing: Bool) -> EventLoopFuture<Void> {
if let connection = self.connection {
// remove read timeout handler
return connection.removeHandler(IdleStateHandler.self).flatMap {
connection.removeHandler(TaskHandler<Delegate>.self)
}.map {
connection.release(closing: closing, logger: self.logger)
}.flatMapError { error in
fatalError("Couldn't remove taskHandler: \(error)")
}
} else {
// TODO: This seems only reached in some internal unit test
// Maybe there could be a better handling in the future to make
// it an error outside of testing contexts
return self.eventLoop.makeSucceededFuture(())
}
self.promise.fail(error)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those functions are not hit from the new implementation. However they are hit from the old implementation. Since we don't want to remove the old implementation in this pr, they should stay for now. We will be able to remove them in a follow up pr.

@@ -290,7 +290,7 @@ class HTTPClientInternalTests: XCTestCase {
let httpBin = HTTPBin()
let httpClient = HTTPClient(eventLoopGroupProvider: .shared(self.clientGroup))
defer {
XCTAssertNoThrow(try httpClient.syncShutdown(requiresCleanClose: true))
XCTAssertNoThrow(try httpClient.syncShutdown())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the new implementation we can not make guarantees about the order of succeeding/failing the request (which will lead to a call to syncShutdown) and marking the connection as idle. For this reason we can not enforce a clean shutdown here.

@fabianfett fabianfett force-pushed the ff-switch-implementation branch 7 times, most recently from 5601745 to 127abc3 Compare September 20, 2021 23:17
@fabianfett fabianfett added this to the HTTP/2 support milestone Sep 20, 2021
@fabianfett fabianfett force-pushed the ff-switch-implementation branch 2 times, most recently from a45c6a7 to 7cd68cb Compare September 22, 2021 14:01
@fabianfett fabianfett added the 🆕 semver/minor Adds new public API. label Sep 22, 2021
@fabianfett fabianfett changed the title [Draft] Implementation switch [HTTPConnectionPool] Implementation switch Sep 22, 2021
@fabianfett fabianfett force-pushed the ff-switch-implementation branch 2 times, most recently from 7deafde to 64eb025 Compare September 22, 2021 14:52
@fabianfett fabianfett marked this pull request as ready for review September 22, 2021 14:52
@@ -34,17 +34,11 @@ extension HTTPClientInternalTests {
("testRequestFinishesAfterRedirectIfServerRespondsBeforeClientFinishes", testRequestFinishesAfterRedirectIfServerRespondsBeforeClientFinishes),
("testProxyStreaming", testProxyStreaming),
("testProxyStreamingFailure", testProxyStreamingFailure),
("testUploadStreamingBackpressure", testUploadStreamingBackpressure),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have replacements for these tests?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. This is now tested way lower in the stack on the connection directly.

@fabianfett fabianfett force-pushed the ff-switch-implementation branch from 64eb025 to a5df5db Compare September 23, 2021 14:42
Copy link
Collaborator

@Lukasa Lukasa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, great work @fabianfett, this looks really good! ✨

@fabianfett
Copy link
Member Author

Apparently we have a new flaky test (see swift-nightly). Will fix in a follow up PR. Merge this one.

@fabianfett fabianfett merged commit 2565dfe into swift-server:main Sep 24, 2021
@fabianfett fabianfett deleted the ff-switch-implementation branch September 24, 2021 07:28
fabianfett added a commit that referenced this pull request Sep 24, 2021
### Motivation

In #427 we switched the implementation over to our new `HTTPConnectionPool`. When we did this, we removed the possibility to access the requests underlying channel. For this reason we needed to remove a number of tests from `HTTPClientInternalTests`. As @weissi pointed out, we should at least still integration test downstream backpressure.

This pr replicates the behavior from `HTTPClientInternalTests.testUploadStreamingBackpressure` directly on the `HTTP1Connection`.

### Changes

- Move and adjust test from `HTTPClientInternalTests.testUploadStreamingBackpressure`
- Rename the test to `testDownloadStreamingBackpressure` since we only test incoming bytes backpressure.

### Result

An integration backpressure test, that survived #427.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🆕 semver/minor Adds new public API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants